package main

import (
	"fmt"
	"net"
	"os"
	"sync"
	"time"
)

//config
const webPort =":8080"                // web请求端口
const clientPort =":8090"             // 客户端连接端口
const maxDataSize = 1024*1024*10      // 请求最大长度（B）

var clientConn net.Conn
var lock sync.Mutex

func getClientConn() net.Conn{
	lock.Lock()
	re:=clientConn
	defer lock.Unlock()
	return re
}

func writeClientConn(conn net.Conn){
	lock.Lock()
	clientConn=conn
	defer lock.Unlock()
}

func checkErrorAndExit(err error,msg string){
	if err != nil{
		fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
		fmt.Println("出错了",msg,err)
		time.Sleep(10*time.Second)
		os.Exit(1)
	}
}

func main() {
	webListen, err := net.Listen("tcp", webPort)
	checkErrorAndExit(err,"监听web端口失败")
	clientListen, err := net.Listen("tcp", clientPort)
	checkErrorAndExit(err,"监听客户端端口失败")
	defer func() {
		_=webListen.Close()
		_=clientListen.Close()
	}()
	go func() {
		for{
			if getClientConn()==nil{
				tmp, err := clientListen.Accept()
				if err != nil{
					fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
					fmt.Println("出错了",err)
					continue
				}
				writeClientConn(tmp)
			}
		}
	}()
	request := make([]byte,maxDataSize)
	response := make([]byte,maxDataSize)
	for{
		webConn,err :=webListen.Accept()
		checkErrorAndExit(err,"与web连接出错")
		requestCnt, err := webConn.Read(request)
		nowClientConn :=getClientConn()
		if nowClientConn == nil {
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
			fmt.Println("客户端未连接",err)
			_=webConn.Close()
			continue
		}
		_, err = nowClientConn.Write(request[:requestCnt])
		if err != nil{
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
			fmt.Println("转发请求失败",err)
			_=webConn.Close()
			writeClientConn(nil)
			continue
		}
		responseCnt, err := nowClientConn.Read(response)
		if err != nil{
			fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
			fmt.Println("接收回复失败",err)
			_=webConn.Close()
			writeClientConn(nil)
			continue
		}
		_, err = webConn.Write(response[:responseCnt])
		_=webConn.Close()
	}
}